<?php

namespace App\Services;

use App\Exceptions\ApiException;
use App\Exceptions\BaseException;
use App\Models\MemberLegal;
use App\Models\Order;
use App\Models\OrderLease;
use App\Models\OrderRemark;
use App\Models\OrderThreeElements;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

/**
 * 新颜的全景雷达和探针
 */
class XinyanService
{

    const  PUBLIC_KEY ='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkSyMMIfJYWJAWAPsHmCNZKQ/mZJxYMBg31dWGz3VLoZbYxetKDl+Z5HktFJ57G4bDKZlcL9LXv8vctnm5Ty+s3V68onOi82WnkfFKNl/rj9B9r6Q0N7buEYVvn77YVlEAE9p7LuDlTLSi8SypqAzNFiizkJZ6K18J8BOtcGBOpDm/c/o45baoN64Mpo7d4K7I1G3VxZ0/L0LGUFPwkmN0voXm/BNf10uhz+Rss0z9uLr5bXjWikUpMpyNitL1fxbxPZPQf3EGppPMywGOBLJnIkwx/q1bKfoQoux4MzGOaecMemC1Q020qjJ/hbUMzyIMH941D60OkiRdRHIBso32QIDAQAB';


// 填充公钥和私钥标记
    public function addStartEnd($key, $startMarker, $endMarker)
    {
        if (strpos($key, $startMarker) === false) {
            $key = $startMarker . $key;
        }
        if (strpos($key, $endMarker) === false) {
            $key = $key . $endMarker;
        }
        return $key;
    }

    public function fillPrivateKeyMarker($privateKey)
    {
        return addStartEnd($privateKey, "-----BEGIN RSA PRIVATE KEY-----\n", "\n-----END RSA PRIVATE KEY-----");
    }

    public function fillPublicKeyMarker($publicKey)
    {
        return self::addStartEnd($publicKey, "-----BEGIN PUBLIC KEY-----\n", "\n-----END PUBLIC KEY-----");
    }

// 加载公钥或私钥
    public  function loadKey($keyStr)
    {
        return openssl_pkey_get_private($keyStr) ?: openssl_pkey_get_public($keyStr);
    }

// RSA加密 (PKCS#1 v1.5)
    public function rsaEncrypt($data, $publicKeyStr)
    {
        $publicKey = self::loadKey(self::fillPublicKeyMarker($publicKeyStr));

        if (!$publicKey) {
            throw new Exception("Invalid public key");
        }

        $dataBytes = $data;
        $maxEncryptBlock = 245; // 2048位RSA的最大加密块大小是245字节

        $encryptedData = '';

        // 分块加密
        $chunks = str_split($dataBytes, $maxEncryptBlock);
        foreach ($chunks as $chunk) {
            $partialEncrypted = '';
            openssl_public_encrypt($chunk, $partialEncrypted, $publicKey, OPENSSL_PKCS1_PADDING);
            $encryptedData .= $partialEncrypted;
        }

        // 转换为Base64格式
        return base64_encode($encryptedData);
    }

// RSA解密 (PKCS#1 v1.5)
    public  function rsaDecrypt($encryptedData, $privateKeyStr)
    {
        $privateKey = loadKey(fillPrivateKeyMarker($privateKeyStr));

        if (!$privateKey) {
            throw new Exception("Invalid private key");
        }

        $encryptedBytes = base64_decode($encryptedData);
        $decryptedData = '';

        // 分块解密
        $chunks = str_split($encryptedBytes, 256); // 对于2048位RSA，每次解密块大小为256字节
        foreach ($chunks as $chunk) {
            $partialDecrypted = '';
            if (!openssl_private_decrypt($chunk, $partialDecrypted, $privateKey, OPENSSL_PKCS1_PADDING)) {
                throw new Exception("Decryption failed, possibly due to incorrect key or corrupted data.");
            }
            $decryptedData .= $partialDecrypted;
        }

        return $decryptedData;
    }




    /**
     * @param string $accessKeySecret 加密秘钥，由运营商提供，用于对数据加密
     * @param array $param_arr 需要加密数组
     * @param string $charset 字符串编码
     * @return string
     * @throws Exception
     */
    public static function getSign($accessKeySecret, $param_arr, $charset = "UTF-8")
    {
        $text = self::getParamsStr($param_arr);
        $key = mb_convert_encoding($accessKeySecret, $charset);
        $data = mb_convert_encoding($text, $charset);
        $hash = hash_hmac('sha1', $data, $key, true);
        return base64_encode($hash);
    }

    /**
     * 对数组按照键值升序排序，得到要加密的原始字符串(格式：key1value1key2value2key3value3 格式)
     * @param array $map
     * @return string
     */
    public static function getParamsStr($map)
    {
        $params = [];
        // 按照键值升序排序
        ksort($map);
        foreach ($map as $key => $value) {
            $params[] = $key . $value;
        }
        return implode('', $params);
    }
    /**
     * 在网时长/open/api/v3/data
     * @param $post
     * @return mixed|void
     */
    public static function onlineTime($post){
        try {


            $result=OrderThreeElements::query()->where('type',1)->where('order_id',$post['orderId'])->value('result');

            if ($result){
                return json_decode($result,true);
            }

            if(Redis::get('onlineTime_order_idab'.$post['orderId'])){
                return true;
            }

            $info=[
                'name' => $post['cert_name'],
                'mobile' => $post['mobile'],
                'id_card' => $post['cert_no'],
            ];

            $baseencrypted= self::rsaEncrypt(json_encode($info), self::PUBLIC_KEY);

            $arguments = [
                // 轩贝科技产品商户ID，由轩贝科技运营提供
                'merchant_id' => 'AHRT01',
                // 轩贝科技访问产品号，由轩贝科技运营提供
                'product_code' => 'XBBR0011',
                // 姓名
                'encrypt_data'=> $baseencrypted,
                // 时间戳（单位：毫秒）
                'time_stamp' => round(microtime(true) * 1000)
            ];


            // 微聚未来产品访问秘钥，由微聚未来运营提供
            $accessKeySecret = "9xURCobb0DXWWqOhcAuWAnioNBb9aZKUEVzsDPkR9j13kJ5jQxzC2rd7nOE6V5uj";
            $sign = self::getSign($accessKeySecret,$arguments);
            $arguments['sign']=$sign;
            $res=http_post('https://open-data.beix.cc/open/api/v3/data',json_encode($arguments),array('Content-Type:application/json'));
            $res=json_decode($res,true);
            self::addLog('在网时长',$arguments,$res);
            if($res['code']=='200'){
                Redis::setEx('onlineTime_order_idab'.$post['orderId'], 7200, 1);

                OrderThreeElements::query()->insert([
                    'type'=>1,
                    'order_id'=>$post['orderId'],
                    'uid'=>$post['uid'],
                    'mobile'=>$post['mobile'],
                    'name'=>$post['cert_name'],
                    'cert_no'=>$post['cert_no'],
                    'status'=>$res['data']['status'],
                    'result'=>json_encode($res['data']),
                    'res'=>json_encode($res),
                    'create_time'=>date('Y-m-d H:i:s'),
                ]);
            }
            return $res['data'];
        } catch (\Exception $e) {
            Log::Info($e->getMessage());
        }
    }

    public static function threeElementsFace($post){
        try {

            $result=OrderThreeElements::query()->where('type',2)->where('uid',$post['uid'])
                ->select( 'mobile','name','cert_no','status')->first();

            if ($result&&$result['status']!=2&&$result['name']==$post['cert_name']&&$result['mobile']==$post['mobile']&&$result['cert_no']==$post['cert_no']){
                return true;
            }
            $info=[
                'name' => $post['cert_name'],
                // 身份证号码
                'id_card' =>  $post['cert_no'],
                // 手机号码
                'mobile' => $post['mobile'],
            ];

            $baseencrypted= self::rsaEncrypt(json_encode($info), self::PUBLIC_KEY);

            $arguments = [
                // 轩贝科技产品商户ID，由轩贝科技运营提供
                'merchant_id' => 'AHRT01',
                // 轩贝科技访问产品号，由轩贝科技运营提供
                'product_code' => 'XBYF00004',
                // 姓名
                'encrypt_data'=> $baseencrypted,
                // 时间戳（单位：毫秒）
                'time_stamp' => round(microtime(true) * 1000)
            ];

            // 微聚未来产品访问秘钥，由微聚未来运营提供
            $accessKeySecret = "9xURCobb0DXWWqOhcAuWAnioNBb9aZKUEVzsDPkR9j13kJ5jQxzC2rd7nOE6V5uj";
            $sign = self::getSign($accessKeySecret,$arguments);
            $arguments['sign']=$sign;
            $res=http_post('https://open-data.beix.cc/open/api/v3/data',json_encode($arguments),array('Content-Type:application/json'));
            $res=json_decode($res,true);
            $arguments['url']='https://open-data.beix.cc/open/api/v3/data';
            self::addLog('运营商三要素',array_merge($arguments,$info),$res);
            if($res['code']=='200'){
                OrderThreeElements::query()->insert([
                    'type'=>2,
                    'uid'=>$post['uid'],
                    'mobile'=>$post['mobile'],
                    'name'=>$post['cert_name'],
                    'cert_no'=>$post['cert_no'],
                    'status'=>$res['data']['result'],
                    'result'=>json_encode($res['data']),
                    'res'=>json_encode($res),
                    'create_time'=>date('Y-m-d H:i:s'),
                ]);
                if($res['data']['result']==2){
                    throw new ApiException('身份证手机号姓名三要素验证失败');
                }
                return true;
            }
            throw new ApiException('身份证手机号姓名三要素验证失败');
        } catch (\Exception $e) {
            throw new ApiException( $e->getMessage());
        }
    }


    /**
     * 运营商三要素
     * @param $post
     * @return mixed|void
     */
    public static function threeElements($post){
        try {


            $result=OrderThreeElements::query()->where('type',2)->where('order_id',$post['orderId'])->value('result');

            if ($result){
                return json_decode($result,true);
            }
            if(Redis::get('threeElements_order_idab'.$post['orderId'])){
                return true;
            }

            $info=[
                'name' => $post['cert_name'],
                // 身份证号码
                'id_card' =>  $post['cert_no'],
                // 手机号码
                'mobile' => $post['mobile'],
            ];

            $baseencrypted= self::rsaEncrypt(json_encode($info), self::PUBLIC_KEY);

            $arguments = [
                // 轩贝科技产品商户ID，由轩贝科技运营提供
                'merchant_id' => 'AHRT01',
                // 轩贝科技访问产品号，由轩贝科技运营提供
                'product_code' => 'XBYF00004',
                // 姓名
                'encrypt_data'=> $baseencrypted,
                // 时间戳（单位：毫秒）
                'time_stamp' => round(microtime(true) * 1000)
            ];

            // 微聚未来产品访问秘钥，由微聚未来运营提供
            $accessKeySecret = "9xURCobb0DXWWqOhcAuWAnioNBb9aZKUEVzsDPkR9j13kJ5jQxzC2rd7nOE6V5uj";
            $sign = self::getSign($accessKeySecret,$arguments);
            $arguments['sign']=$sign;
            $res=http_post('https://open-data.beix.cc/open/api/v3/data',json_encode($arguments),array('Content-Type:application/json'));
            $res=json_decode($res,true);
            self::addLog('运营商三要素',$arguments,$res);
            if($res['code']=='200'){
                Redis::setEx('threeElements_order_idab'.$post['orderId'], 7200, 1);

                OrderThreeElements::query()->insert([
                    'type'=>2,
                    'order_id'=>$post['orderId'],
                    'uid'=>$post['uid'],
                    'mobile'=>$post['mobile'],
                    'name'=>$post['cert_name'],
                    'cert_no'=>$post['cert_no'],
                    'status'=>$res['data']['result'],
                    'result'=>json_encode($res['data']),
                    'res'=>json_encode($res),
                    'create_time'=>date('Y-m-d H:i:s'),
                ]);
            }

            return $res['data'];
        } catch (\Exception $e) {
            Log::Info($e->getMessage());
        }
    }



    /**
     * 探针C（信用探查指数）新颜雷达
     * @param $post
     * @return mixed|void
     */
    public static function fxTan($post){
        // Example usage
        try {
            $info= [

                // 姓名
                'name' => $post['cert_name'],
                // 身份证号码
                'id_card' =>  $post['cert_no'],
                // 手机号码
                'mobile' => $post['mobile'],
                // 时间戳（单位：毫秒）
                'time_stamp' => round(microtime(true) * 1000)
            ];

            $baseencrypted= self::rsaEncrypt(json_encode($info), self::PUBLIC_KEY);

            $arguments = [
                // 轩贝科技产品商户ID，由轩贝科技运营提供
                'merchant_id' => 'AHRT01',
                // 轩贝科技访问产品号，由轩贝科技运营提供
                'product_code' => 'DLPDHN12',
                // 姓名
                'encrypt_data'=> $baseencrypted,
                // 时间戳（单位：毫秒）
                'time_stamp' => round(microtime(true) * 1000)
            ];

            // 微聚未来产品访问秘钥，由微聚未来运营提供
            $accessKeySecret = "9xURCobb0DXWWqOhcAuWAnioNBb9aZKUEVzsDPkR9j13kJ5jQxzC2rd7nOE6V5uj";
            $sign = self::getSign($accessKeySecret,$arguments);
            $arguments['sign']=$sign;

            $res=http_post('https://open-data.beix.cc/open/api/v3/data',json_encode($arguments),array('Content-Type:application/json'));
            $res=json_decode($res,true);
            self::addLog('新颜雷达',$arguments,$res);
            return $res;
        } catch (\Exception $e) {
            Log::Info($e->getMessage());
            throw new ApiException( $e->getMessage());
        }
    }



    /**
     * 司法数据（个人）
     * @param $post
     * @return mixed|void
     */
    public static function fsUserData($post){
        try {
            $info=[
                'name' => $post['cert_name'],
                'id_card' =>  $post['cert_no'],
                'mobile' => $post['mobile']
            ];
            $uid=$post['uid']??0;

            $baseencrypted= (new XinyanService)->rsaEncrypt(json_encode($info), self::PUBLIC_KEY);

            $arguments = [
                // 轩贝科技产品商户ID，由轩贝科技运营提供
                'merchant_id' => 'AHRT01',
                // 轩贝科技访问产品号，由轩贝科技运营提供
                'product_code' => 'XBJX1011',
                // 姓名
                'encrypt_data'=> $baseencrypted,
                // 时间戳（单位：毫秒）
                'time_stamp' => time()*1000
            ];
            //            dd($arguments);
            // 微聚未来产品访问秘钥，由微聚未来运营提供
            $accessKeySecret = "9xURCobb0DXWWqOhcAuWAnioNBb9aZKUEVzsDPkR9j13kJ5jQxzC2rd7nOE6V5uj";
            $sign = self::getSign($accessKeySecret,$arguments);
            $arguments['sign']=$sign;
            $res=http_post('https://open-data.beix.cc/open/api/v3/data',json_encode($arguments),array('Content-Type:application/json'));
            $res=json_decode($res,true);

            self::addLog('法诉雷达',$arguments,$res);
            $detail=$res['data'];
            $legal=0;
            if($detail['consumptionRestrictionList']||$detail['breachCaseList']||
                ($detail['lawsuitStat']['implement']['count']['count_total']>0&&$detail['lawsuitStat']['implement']['cases'][0]['n_ssdw']=='被执行人')){

                $cisuedate=$detail['consumptionRestrictionList'][0]['issueDate']?strtotime($detail['consumptionRestrictionList'][0]['issueDate']):'';
                if($detail['consumptionRestrictionList']&&$cisuedate&&$cisuedate>strtotime('-2 year')) {
                    $legal=1;
                }

                $bisuedate=$detail['breachCaseList'][0]['issueDate']?strtotime($detail['breachCaseList'][0]['issueDate']):'';

                if($detail['breachCaseList']&&$bisuedate&&$bisuedate>strtotime('-2 year')){
                    $legal=1;
                }

                $disuedate=$detail['lawsuitStat']['implement']['cases'][0]['d_jarq']?strtotime($detail['lawsuitStat']['implement']['cases'][0]['d_jarq']):'';

                if($detail['lawsuitStat']['implement']['cases']&&$disuedate&&$disuedate>strtotime('-2 year')){
                    $legal=1;
                }

                if($legal){
                    $resa=json_encode($res);
                    Redis::set('user_legal_black'.$uid,$uid);
                    MemberLegal::insertMemberLegal($post['cert_no'],$post['cert_name'],$post['mobile'],$uid,0,$resa);
                }else{
                    $resa=json_encode($res);
                    MemberLegal::insertMemberLegal($post['cert_no'],$post['cert_name'],$post['mobile'],$uid,1,$resa);
                }

            }else{
                $resa=json_encode($res);
                MemberLegal::insertMemberLegal($post['cert_no'],$post['cert_name'],$post['mobile'],$uid,1,$resa);
            }
            return $res;
        } catch (\Exception $e) {
            Log::Info($e->getMessage());
            self::addLog($e->getMessage());
        }
    }





    public static function addLog($message,$request=[],$response=[]){
        $content = [
            'request'=>is_object($request) ? object_array($request) : $request,
            'response'=>is_object($response) ? object_array($response) : $response,
        ];
        \Illuminate\Support\Facades\Log::channel("customerinfo")->debug($message,$content);
    }





}
